package com.example.apartment.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.apartment.common.ApiRestResponse;
import com.example.apartment.common.RespException;
import com.example.apartment.common.RespExceptionEnum;
import com.example.apartment.domain.Admin;
import com.example.apartment.domain.Building;
import com.example.apartment.mapper.AdminMapper;
import com.example.apartment.mapper.BuildingMapper;
import com.example.apartment.mapper.RoomMapper;
import com.example.apartment.service.BuildingService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
 * 宿舍楼业务层实现类
 *
 * @author wuzexin
 * @date 2021/11/2 13:42
 */
@Service
public class BuildingServiceImpl implements BuildingService {

    @Resource
    private BuildingMapper buildingMapper;
    @Resource
    private RoomMapper roomMapper;
    @Resource
    private AdminMapper adminMapper;

    /*
        判断管理员是否拥有权限
        role: 1-系统管理员 2-宿舍楼管理员 3-未审核不可登录状态
        只有系统管理员拥有宿舍楼管理权限
     */

    /**
     * 创建宿舍楼
     *
     * @param admin        管理员用户信息
     * @param buildingName 宿舍楼名字
     * @param floorCount   宿舍楼层数
     * @param roomCount    宿舍楼房间数
     * @return 宿舍楼信息
     */
    @Override
    public Building create(Admin admin, String buildingName, Integer floorCount, Integer roomCount) {
        // 判断用户是否为系统管理员
        if (admin.getRole() != 1) {
            // 不是则抛出权限不够异常
            throw new RespException(RespExceptionEnum.NEED_PERMISSIONS);
        }

        // 判断宿舍楼名字是否已经存在
        QueryWrapper queryWrapper1 = new QueryWrapper();
        queryWrapper1.eq("building_name", buildingName);
        Building building1 = buildingMapper.selectOne(queryWrapper1);
        if (building1 != null) {
            // 如果存在则抛出宿舍名已存在异常
            throw new RespException(RespExceptionEnum.BUILDING_NAME_EXISTS);
        }

        // 创建一个Building实体对象，将信息放入对象中
        Building building = new Building();
        building.setBuildingName(buildingName);
        building.setFloorCount(floorCount);
        building.setRoomCount(roomCount);

        // 将对象存入数据库
        int insert = buildingMapper.insert(building);

        // 如果insert==0 抛出新增失败异常
        if (insert == 0) {
            throw new RespException(RespExceptionEnum.INSERT_FAILED);
        }

        return building;
    }

    /**
     * 修改宿舍楼信息
     *
     * @param admin           管理员用户信息
     * @param id              宿舍楼id
     * @param buildingName 宿舍楼新名字
     * @param floorCount   宿舍新楼层数
     * @param roomCount    宿舍楼新房间数
     * @return
     */
    @Override
    public Building update(Admin admin, Integer id, String buildingName, Integer floorCount, Integer roomCount) {

        // 判断用户是否为系统管理员
        if (admin.getRole() != 1) {
            // 不是则抛出权限不够异常
            throw new RespException(RespExceptionEnum.NEED_PERMISSIONS);
        }

        // 根据id获取宿舍楼信息
        Building building = buildingMapper.selectById(id);
        // 如果building不存在，则抛出异常
        if (building == null) {
            throw new RespException(RespExceptionEnum.BUILDING_NOT_EXISTS);
        }

        // 判断如果宿舍楼更改，新宿舍楼名字是否重复
        if (!building.getBuildingName().equals(buildingName)) {
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq("building_name", buildingName);
            Building building1 = buildingMapper.selectOne(queryWrapper);
            // 如果存在，则抛出宿舍楼名字已存在异常
            if (building1 != null) {
                throw new RespException(RespExceptionEnum.BUILDING_NAME_EXISTS);
            }
            building.setBuildingName(buildingName);
        }

        building.setFloorCount(floorCount);
        building.setRoomCount(roomCount);

        // 更新数据库
        int count = buildingMapper.updateById(building);

        // 判断count是否为0， 如果是则抛出更新失败异常
        if (count == 0) {
            throw new RespException(RespExceptionEnum.UPDATE_FAILED);
        }

        return building;
    }

    /**
     * 删除宿舍楼
     *
     * @param admin 管理员用户信息
     * @param id    宿舍楼id
     */
    @Override
    public void delete(Admin admin, Integer id) {

        // 判断用户是否为系统管理员
        if (admin.getRole() != 1) {
            // 不是则抛出权限不够异常
            throw new RespException(RespExceptionEnum.NEED_PERMISSIONS);
        }

        // 判断该宿舍楼是否还存在对应房间
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("building_id", id);
        List roomList = roomMapper.selectList(queryWrapper);
        if (!roomList.isEmpty()) {
            throw new RespException(RespExceptionEnum.BUILDING_NOT_EMPTY);
        }

        // 数据库删除宿舍楼信息
        int count = buildingMapper.deleteById(id);

        // 如果count!=1， 抛出删除失败异常
        if (count != 1) {
            throw new RespException(RespExceptionEnum.DELETE_FAILED);
        }
    }

    /**
     * 查询所有宿舍楼信息(增加了宿管查看所有宿舍楼的权限)
     *
     * @param admin
     * @return
     */
    @Override
    public List<Building> select(Admin admin) {

        // 判断用户是否为系统管理员
        if (admin.getRole() != 1 && admin.getRole() != 2) {
            // 不是则抛出权限不够异常
            throw new RespException(RespExceptionEnum.NEED_PERMISSIONS);
        }

        List<Building> list = buildingMapper.selectList(null);

        // 将宿舍管理员username和cellphone添加到对应的building中
        for (Building building : list) {
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq("building_id", building.getId());
            Admin admin1 = adminMapper.selectOne(queryWrapper);

            if (admin1 != null) {
                building.setUsername(admin1.getUsername());
                building.setCellphone(admin1.getCellphone());
            }
        }

        // 返回所有宿舍楼信息
        return list;
    }

    /**
     * 根据id查询宿舍楼
     *
     * @param admin 管理员信息
     * @param id    宿舍楼id
     * @return 宿舍楼信息
     */
    @Override
    public Building selectById(Admin admin, Integer id) {

        // 判断用户是否为系统管理员
        if (admin.getRole() != 1) {
            // 不是则抛出权限不够异常
            throw new RespException(RespExceptionEnum.NEED_PERMISSIONS);
        }

        // 返回宿舍楼信息
        return buildingMapper.selectById(id);
    }
}
